package com.ruicar.afs.cloud.afscase.infomanagement.service.impl;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.afscase.infomanagement.condition.CarInfoCondition;
import com.ruicar.afs.cloud.afscase.infomanagement.condition.CaseInfoQueryCondition;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseBaseInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseCarInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseCarStyleDetail;
import com.ruicar.afs.cloud.afscase.infomanagement.mapper.CaseCarInfoMapper;
import com.ruicar.afs.cloud.afscase.infomanagement.service.*;
import com.ruicar.afs.cloud.afscase.maxloanparam.entity.MaxLoanParam;
import com.ruicar.afs.cloud.afscase.maxloanparam.service.MaxLoanParamService;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinFinancingItems;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyFinancingItemsService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>Description: </p>
 *
 * @author ZC.GUO
 * @version 1.0
 * @date create on 2020-05-13 15:20
 */
@Service
@AllArgsConstructor
@Data
@Slf4j
public class CaseCarInfoServiceImpl extends ServiceImpl<CaseCarInfoMapper, CaseCarInfo> implements CaseCarInfoService {

    private CaseCostInfoService caseCostInfoService;

    private CaseBaseInfoService caseBaseInfoService;

    private CaseCarStyleDetailService carStyleDetailInfoService;

    private CaseCarInfoMapper caseCarInfoMapper;

    private CaseFinancingItemsService  caseFinancingItemsService;

    private MaxLoanParamService maxLoanParamService;

    private ApplyFinancingItemsService financingItemsService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public BigDecimal calculateLoanAmtMaxByCar(CaseInfoQueryCondition caseInfoQueryCondition) {

        CaseCarInfo caseCarInfo = this.getOne(Wrappers.<CaseCarInfo>query().lambda()
                .eq(CaseCarInfo::getId, Long.parseLong(caseInfoQueryCondition.getCarId()))
        );

        if (ObjectUtils.isEmpty(caseCarInfo)) {
            return null;
        }

        CaseBaseInfo caseBaseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>query().lambda()
                .eq(CaseBaseInfo::getApplyNo, caseCarInfo.getApplyNo()));

        /**  车款  **/
        FinCostDetails carAmtCostInfo = caseCostInfoService.getOne(Wrappers.<FinCostDetails>query().lambda()
                .eq(FinCostDetails::getCarId, caseCarInfo.getId())
                .eq(FinCostDetails::getCostType, CostTypeEnum.CARAMT.getCode()));


        /**  附加贷  **/
        List<FinFinancingItems> financingItemsList =financingItemsService.getFinancingItemsList(caseCarInfo.getApplyNo(),caseCarInfo.getId());
        BigDecimal affifxCostInfo=BigDecimal.ZERO;
        for(FinFinancingItems finFinancingItems:financingItemsList){
            affifxCostInfo=affifxCostInfo.add(finFinancingItems.getFinanceItemAmt());
        }
        /**  新车  **/
        if (BusinessTypeEnum.NEW_CAR.getCode().equals(caseBaseInfo.getBusinessType())) {
            /**业务类型”为新车且“车辆类型”为 LCV 且“车辆属性”为挂牌新车*/
            if (CarTypeEnum.LCV.getCode().equals(caseBaseInfo.getCarType()) &&CarNatureEnum.PLATE_CAR.getCode().equals(caseBaseInfo.getCarNature())) {
               /* return this.lcvCar(caseInfoQueryCondition, caseCarInfo, carAmtCostInfo, affifxCostInfo);*/
            }
            /**车用车并且车辆属性是‘新车’**/
            else if(CarTypeEnum.PASSENGER_CAR.getCode().equals(caseBaseInfo.getCarType())&&CarNatureEnum.NEW_CAR.getCode().equals(caseBaseInfo.getCarNature())){
                CaseCarStyleDetail caseCarStyleDetail = carStyleDetailInfoService.getOne(Wrappers.<CaseCarStyleDetail>query().lambda()
                        .eq(CaseCarStyleDetail::getCarId, caseCarInfo.getId()));
                if (ObjectUtils.isNotEmpty(caseCarStyleDetail)){
                    /**运营方式无*/
                    if(OperateWayEnum.NO.getCode().equals(caseBaseInfo.getOperateWay())){
                        return this.operateWayNo(caseInfoQueryCondition, caseCarInfo, carAmtCostInfo, affifxCostInfo,caseCarStyleDetail);
                    }
                    /**运营方式网约车*/
                    else  if (OperateWayEnum.NETWORK_CAR.getCode().equals(caseBaseInfo.getOperateWay())){
                        return this.operateWayOnline(caseInfoQueryCondition, caseCarInfo, carAmtCostInfo, affifxCostInfo,caseCarStyleDetail);
                    }
                }else{
                    throw new AfsBaseException("计算失败,车辆详情信息不全！");
                }

            }

        }
        /**  二手车  **/
        else if (BusinessTypeEnum.OLD_CAR.getCode().equals(caseBaseInfo.getBusinessType())) {
            //乘用车并且车辆属性为二手车时
            if (CarTypeEnum.PASSENGER_CAR.getCode().equals(caseBaseInfo.getCarType())
                    && CarNatureEnum.OLD_CAR.getCode().equals(caseBaseInfo.getCarNature())) {
                return this.commonOldCar(caseInfoQueryCondition, caseCarInfo, carAmtCostInfo, affifxCostInfo);
            }
            /**  试乘试驾车 TODO GJQ 暂时不做 业务逻辑留下 **/
            else if (CarNatureEnum.TEST_CAR.getCode().equals(caseBaseInfo.getCarNature())) {
                return this.oldTestCar(caseInfoQueryCondition, caseCarInfo, carAmtCostInfo, affifxCostInfo);

            }

        }
        /**  挂牌车 TODO GJQ 暂时不做 业务逻辑留下 **/
       /* else {
            return this.plateCar(caseBaseInfo, caseInfoQueryCondition, caseCarInfo, carAmtCostInfo, affifxCostInfo);
        }*/
        return null;
    }

    /**
     * lcvCar
     * <p>Description:新车-LCV最大贷款额 </p>
     *
     * @param
     * @return
     */
    private BigDecimal lcvCar(CaseInfoQueryCondition caseInfoQueryCondition, CaseCarInfo caseCarInfo, FinCostDetails carAmtCostInfo, BigDecimal askedAffifxPrice) {

        /**  可接受的裸车价格=min(销售价格、认定价格)  **/
        BigDecimal acceptCarPrice = minDecimal(caseCarInfo.getSalePrice(), caseInfoQueryCondition.getFirmPrice());
        BigDecimal lcvCarAffifxRate;
        BigDecimal maxLoanRate;
        /**  **/
        MaxLoanParam  maxLoanParam=this.getMaxLoanParam(MaxLoanParamEnum.CONVENTIONAL_NEWCAR_LCV_PLATE.getCode());
        if(ObjectUtils.isEmpty(maxLoanParam)){
            throw  new  AfsBaseException("非新能源业务类型为新车且车辆类型为乘用车且车辆属性为新车且运营方式为无参数不存在！");
        }
        lcvCarAffifxRate = maxLoanParam.getAdditionalRate();
        maxLoanRate = maxLoanParam.getMaxLoanRate();
        /**  可接受的附加价格=min(申报的附加价格、可接受的裸车价格*LCV附加贷比例上限) **/
        BigDecimal acceptAffifxPrice = minDecimal(askedAffifxPrice, acceptCarPrice.multiply(lcvCarAffifxRate));
        /**  可接受的最大贷款额=（可接受的裸车价格+可接受的附加贷金额）*最大融资比例  **/
        BigDecimal loanAmtMax = (acceptCarPrice.add(acceptAffifxPrice)).multiply(maxLoanRate);


        /**  保存认定价格和理论最大贷款额  **/
        caseCarInfo.setFirmPrice(caseInfoQueryCondition.getFirmPrice());
        caseCarInfo.setLoanAmtMax(loanAmtMax);
        this.updateById(caseCarInfo);

        return loanAmtMax;
    }

    /**
     * @description: 理想最大额运营方式无
     * @author jiaqi.guo
     * @created 2020/8/28 17:13
     * @version 1.0
     */
    private BigDecimal operateWayNo( CaseInfoQueryCondition caseInfoQueryCondition, CaseCarInfo caseCarInfo, FinCostDetails carAmtCostInfo, BigDecimal askedAffifxPrice,CaseCarStyleDetail styleDetail) {
        /**  可接受的裸车价格=min(销售价格、认定价格)  **/
        BigDecimal acceptCarPrice = minDecimal(caseCarInfo.getSalePrice(), caseInfoQueryCondition.getFirmPrice());
        BigDecimal greenPassengerCarAffifxRate;
        BigDecimal maxLoanRate;

        if (AfsEnumUtil.key(WhetherEnum.NO).equals(styleDetail.getIsGreen())) { //非新能源乘用车运用方式'无'
            MaxLoanParam  maxLoanParam=this.getMaxLoanParam(MaxLoanParamEnum.CONVENTIONAL_NEWCAR_PASSENGER_NO.getCode());
            if(ObjectUtils.isEmpty(maxLoanParam)){
                throw  new  AfsBaseException("非新能源业务类型为新车且车辆类型为乘用车且车辆属性为新车且运营方式为无参数不存在！");
            }
            greenPassengerCarAffifxRate = maxLoanParam.getAdditionalRate();
            maxLoanRate = maxLoanParam.getMaxLoanRate();
        } else {
            MaxLoanParam  maxLoanParam=this.getMaxLoanParam(MaxLoanParamEnum.ENERGY_NEWCAR_PASSENGER_NO.getCode());
            if(ObjectUtils.isEmpty(maxLoanParam)){
                throw  new  AfsBaseException("新能源业务类型为新车且车辆类型为乘用车且车辆属性为新车且运营方式为无参数不存在！");
            }//新能源乘用车运用方式'无'
            greenPassengerCarAffifxRate = maxLoanParam.getAdditionalRate();
            maxLoanRate = maxLoanParam.getMaxLoanRate();
        }

        /**  可接受的附加价格=min(申报的附加价格、可接受的裸车价格*多品牌新能源乘用车附加贷比例上限)  **/
        BigDecimal acceptAffifxPrice = minDecimal(askedAffifxPrice, acceptCarPrice.multiply(greenPassengerCarAffifxRate));
        /**  理想最大带宽额度=（可接受的裸车价格+可接受的附加贷金额）*最大融资比例  **/
        BigDecimal loanAmtMax = (acceptCarPrice.add(acceptAffifxPrice)).multiply(maxLoanRate);

        /**  保存认定价格和理论最大贷款额  **/
        caseCarInfo.setFirmPrice(caseInfoQueryCondition.getFirmPrice());
        caseCarInfo.setLoanAmtMax(loanAmtMax);
        this.updateById(caseCarInfo);

        return loanAmtMax;
    }

  /**
   * @description: 理想最大贷款额网约车
   * @author jiaqi.guo
   * @created 2020/8/28 17:12
   * @version 1.0
   */
    private BigDecimal operateWayOnline( CaseInfoQueryCondition caseInfoQueryCondition, CaseCarInfo caseCarInfo, FinCostDetails carAmtCostInfo, BigDecimal askedAffifxPrice,CaseCarStyleDetail styleDetail) {

        /**  可接受的裸车价格=min(销售价格、认定价格)  **/
        BigDecimal acceptCarPrice = minDecimal(caseCarInfo.getSalePrice(), caseInfoQueryCondition.getFirmPrice());
        BigDecimal greenPassengerCarAffifxRate;
        BigDecimal maxLoanRate;
        if (AfsEnumUtil.key(WhetherEnum.NO).equals(styleDetail.getIsGreen())) { //非新能源乘用车运用方式'网约车'
            MaxLoanParam  maxLoanParam=this.getMaxLoanParam(MaxLoanParamEnum.CONVENTIONAL_NEWCAR_PASSENGER_NET.getCode());
            if(ObjectUtils.isEmpty(maxLoanParam)){
                throw  new  AfsBaseException("非新能源业务类型为新车且车辆类型为乘用车且车辆属性为新车且运营方式为网约车参数不存在！");
            }
            greenPassengerCarAffifxRate = maxLoanParam.getAdditionalRate();
            maxLoanRate = maxLoanParam.getMaxLoanRate();
        } else {                                                          //新能源乘用车运用方式'网约车'
            MaxLoanParam  maxLoanParam=this.getMaxLoanParam(MaxLoanParamEnum.ENERGY_NEWCAR_PASSENGER_NET.getCode());
            if(ObjectUtils.isEmpty(maxLoanParam)){
                throw  new  AfsBaseException("新能源业务类型为新车且车辆类型为乘用车且车辆属性为新车且运营方式为网约车参数不存在！");
            }
            greenPassengerCarAffifxRate = maxLoanParam.getAdditionalRate();
            maxLoanRate = maxLoanParam.getMaxLoanRate();
        }

        /**  可接受的附加价格=min(申报的附加价格、可接受的裸车价格*多品牌新能源乘用车附加贷比例上限)  **/
        BigDecimal acceptAffifxPrice = minDecimal(askedAffifxPrice, acceptCarPrice.multiply(greenPassengerCarAffifxRate));
        /**  理想最大带宽额度=（可接受的裸车价格+可接受的附加贷金额）*最大融资比例  **/
        BigDecimal loanAmtMax = (acceptCarPrice.add(acceptAffifxPrice)).multiply(maxLoanRate);

        /**  保存认定价格和理论最大贷款额  **/
        caseCarInfo.setFirmPrice(caseInfoQueryCondition.getFirmPrice());
        caseCarInfo.setLoanAmtMax(loanAmtMax);
        this.updateById(caseCarInfo);

        return loanAmtMax;
    }

    /**
     * @description:  试乘试驾驶 TODO GJQ 暂时不做 业务逻辑留下
     * @author jiaqi.guo
     * @created 2020/8/28 20:06
     * @version 1.0
     */
    private BigDecimal oldTestCar(CaseInfoQueryCondition caseInfoQueryCondition, CaseCarInfo caseCarInfo, FinCostDetails carAmtCostInfo, BigDecimal askedAffifxPrice) {

        MaxLoanParam  maxLoanParam=this.getMaxLoanParam(MaxLoanParamEnum.OLDCAR_PASSENGER_TEST_CAR.getCode());
        if(ObjectUtils.isEmpty(maxLoanParam)){
            throw  new  AfsBaseException("试乘试驾车参数不存在！");
        }
        BigDecimal testCarAffifxRate = maxLoanParam.getAdditionalRate();
        BigDecimal maxLoanRate = maxLoanParam.getMaxLoanRate();

        /**  可接受的裸车价格=min(销售价格、评估价格)；  **/
        BigDecimal acceptCarPrice = minDecimal(caseCarInfo.getSalePrice(), caseInfoQueryCondition.getEvaluatingPrice());

        /**  可接受的附加价格=min(申报的附加价格、可接受的裸车价格*试乘试驾车附加贷比例上限)  **/
        BigDecimal acceptAffifxPrice = minDecimal(askedAffifxPrice, acceptCarPrice.multiply(testCarAffifxRate));

        /**  可接受的最大贷款额=（可接受的裸车价格+可接受的附加贷金额*最大融资比例；  **/
        BigDecimal loanAmtMax = (acceptCarPrice.add(acceptAffifxPrice)).multiply(maxLoanRate);

        /**  保存认定价格和理论最大贷款额  **/
        caseCarInfo.setEvaluatingPrice(caseInfoQueryCondition.getEvaluatingPrice());
        caseCarInfo.setLoanAmtMax(loanAmtMax);
        this.updateById(caseCarInfo);

        return loanAmtMax;
    }

    /**
     * @description: 适用于“业务类型”为二手车且“车辆类型”为乘用车且“车辆属性”为二手车的这个场景
     * @author jiaqi.guo
     * @created 2020/8/27 16:55
     * @version 1.0
     */
    private BigDecimal commonOldCar(CaseInfoQueryCondition caseInfoQueryCondition, CaseCarInfo caseCarInfo, FinCostDetails carAmtCostInfo, BigDecimal askedAffifxPrice) {
        MaxLoanParam  maxLoanParam=this.getMaxLoanParam(MaxLoanParamEnum.OLDCAR_PASSENGER_OLDCAR.getCode());
        if(ObjectUtils.isEmpty(maxLoanParam)){
            throw  new  AfsBaseException("业务类型为二手车且车辆类型为乘用车且车辆属性为二手车参数不存在！");
        }
        /** 二手车附加贷比例上限后续从参数表中获取 **/
        BigDecimal oldCarAffifxRate = maxLoanParam.getAdditionalRate();

        /**  最大融资比例后续从参数表中获取  **/
        BigDecimal maxLoanRate = maxLoanParam.getMaxLoanRate();

        /**  可接受的裸车价格=min(销售价格、评估价格)  **/
        BigDecimal acceptCarPrice = minDecimal(caseCarInfo.getSalePrice(), caseInfoQueryCondition.getEvaluatingPrice());


        /**  可接受的附加价格=min(申报的附加价格、可接受的裸车价格*二手车附加贷比例上限)  **/
        BigDecimal acceptAffifxPrice = minDecimal(askedAffifxPrice, acceptCarPrice.multiply(oldCarAffifxRate));

        /**  可接受的最大贷款额=（可接受的裸车价格+可接受的附加贷金额）*最大融资比例；  **/
        BigDecimal loanAmtMax = (acceptCarPrice.add(acceptAffifxPrice)).multiply(maxLoanRate);

        /**  保存认定价格和理论最大贷款额  **/
        caseCarInfo.setEvaluatingPrice(caseInfoQueryCondition.getEvaluatingPrice());
        caseCarInfo.setLoanAmtMax(loanAmtMax);
        this.updateById(caseCarInfo);

        return loanAmtMax;
    }

    /**
     * minDecimal
     * <p>Description: 获取最小值，空值按照0计算</p>
     *
     * @param
     * @return
     */
    private BigDecimal minDecimal(BigDecimal decimalOne, BigDecimal decimalTwo) {
        if (ObjectUtils.isEmpty(decimalOne)) {
            decimalOne = BigDecimal.ZERO;
        }
        if (ObjectUtils.isEmpty(decimalTwo)) {
            decimalTwo = BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(Math.min(decimalOne.doubleValue(), decimalTwo.doubleValue()));
    }

    /**
     * @description: 根据唯一标识查询参数
     * @author jiaqi.guo
     * @created 2020/8/29 18:01
     * @version 1.0
     */
    public MaxLoanParam getMaxLoanParam(String paramLogo){
        MaxLoanParam  maxLoanParam=maxLoanParamService.getOne(Wrappers.<MaxLoanParam>query().lambda()
        .eq(StringUtils.isNotBlank(paramLogo),MaxLoanParam::getParamLogo,paramLogo));
        return  maxLoanParam;
    }
    /**
     * @description: 根据条件获取车辆信息
     * @author jiaqi.guo
     * @created 2020/9/1 19:13
     * @version 1.0
     */
    @Override
    public List<CaseCarInfo> getAllCarInfo(CarInfoCondition carInfoCondition){
       return baseMapper.getAllCarInfo(carInfoCondition);
    }
}
